package com.szly.phm.common.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.szly.phm.common.entity.dto.permission.CreatePermissionDTO;
import com.szly.phm.common.entity.dto.permission.PermissionDTO;
import com.szly.phm.common.entity.dto.permission.PermissionSortDTO;
import com.szly.phm.common.entity.dto.permission.UpdatePermissionDTO;
import com.szly.phm.common.entity.dto.user.LoginUserDTO;
import com.szly.phm.common.entity.po.SysPermission;
import com.szly.phm.common.entity.po.SysRolePermission;
import com.szly.phm.common.entity.po.TaAlgorithmModelLibrary;
import com.szly.phm.common.entity.result.CodeStatusEnum;
import com.szly.phm.common.entity.result.PageResult;
import com.szly.phm.common.entity.result.RootResponse;
import com.szly.phm.common.entity.vo.permissiom.PermissionTreeVO;
import com.szly.phm.common.entity.vo.permissiom.PermissionVO;
import com.szly.phm.common.mapper.SysOperationMapper;
import com.szly.phm.common.mapper.SysPermissionMapper;
import com.szly.phm.common.mapper.SysRolePermissionMapper;
import com.szly.phm.common.service.ISysPermissionService;
import com.szly.phm.common.utils.BeanCopyUtils;
import com.szly.phm.common.utils.HandleUtils;
import com.szly.phm.common.utils.MenuTree;
import com.szly.phm.common.utils.PcbsException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-07-02
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService {

    private final SysRolePermissionMapper rolePermissionMapper;

    private final SysOperationMapper sysOperationMapper;
//    @Override
//    public HashSet<LoginPermissionVO> queryPermissionsByRoleIds(List<String> roleIds, AtomicBoolean supperAdmin) {
//        var lps = new HashSet<LoginPermissionVO>();
//        List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
//        if (!HandleUtils.ListIsNotNull(roleIds)) {
//            return lps;
//        }
//        var permissions = new ArrayList<SysPermission>();
//        if (supperAdmin.get()) {
//            var wrapper = new LambdaQueryWrapper<SysPermission>();
//            wrapper.eq(SysPermission::getIsSoftDelete, false);
//            wrapper.orderByDesc(SysPermission::getSort);
//            permissions = (ArrayList<SysPermission>) baseMapper.selectList(wrapper);
//        } else {
//            permissions = baseMapper.queryPermissionsByRoleId(roleIds);
////            var wrapper = new LambdaQueryWrapper<SysPermission>();
////            List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
////            wrapper.eq(SysPermission::getIsSoftDelete, false);
//            permissions.forEach(p->{
//                var permissionTreeVO=new PermissionTreeVO();
//                BeanCopyUtils.copy(p,permissionTreeVO);
//                permissionTreeVOList.add(permissionTreeVO);
//            });
//            if( permissionTreeVOList!=null&&permissionTreeVOList.size()!=0) {
//                MenuTree menuTree = new MenuTree(permissionTreeVOList);
//                var menuList = menuTree.builTree();
//                menuList.forEach(m -> {
//                    if (m.getPermissionTreeVOList() != null && m.getPermissionTreeVOList().size() != 0) {
//                        m.setButton(false);
//                        getData(m.getPermissionTreeVOList(), roleIds);
//                    }
//                });
//
//            }
//        }
//        if (HandleUtils.ListIsNotNull(permissions)) {
//            permissions.forEach(m -> {
//                var p = new LoginPermissionVO();
//                BeanCopyUtils.copy(m, p);
//                lps.add(p);
//            });
//        }
//        return lps;
//    }

    @Override
    public List<PermissionTreeVO> queryPermissionsByRoleIds1(List<String> roleIds, AtomicBoolean supperAdmin) {
        List<PermissionTreeVO> menuList=new ArrayList<>();
        List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
        if (!HandleUtils.ListIsNotNull(roleIds)) {
            return menuList;
        }
        var permissions = new ArrayList<SysPermission>();
        if (supperAdmin.get()) {
            var wrapper = new LambdaQueryWrapper<SysPermission>();
            wrapper.eq(SysPermission::getIsSoftDelete, false);
            wrapper.orderByAsc(SysPermission::getSort);
            permissions = (ArrayList<SysPermission>) baseMapper.selectList(wrapper);
            permissions.forEach(p->{
                var permissionTreeVO=new PermissionTreeVO();
                BeanCopyUtils.copy(p,permissionTreeVO);
                permissionTreeVOList.add(permissionTreeVO);
            });
            if( permissionTreeVOList!=null&&permissionTreeVOList.size()!=0) {
                MenuTree menuTree = new MenuTree(permissionTreeVOList);
                menuList = menuTree.builTree();
                menuList.forEach(m -> {
                    if (m.getPermissionTreeVOList() != null && m.getPermissionTreeVOList().size() != 0) {
                        m.setButton(false);
                        getDataAdmin(m.getPermissionTreeVOList(), roleIds);
                    }
                });

            }
        } else {
            permissions = baseMapper.queryPermissionsByRoleId(roleIds);
//            var wrapper = new LambdaQueryWrapper<SysPermission>();
//            List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
//            wrapper.eq(SysPermission::getIsSoftDelete, false);
            permissions.forEach(p->{
                var permissionTreeVO=new PermissionTreeVO();
                BeanCopyUtils.copy(p,permissionTreeVO);
                permissionTreeVOList.add(permissionTreeVO);
            });
            if( permissionTreeVOList!=null&&permissionTreeVOList.size()!=0) {
                MenuTree menuTree = new MenuTree(permissionTreeVOList);
                 menuList = menuTree.builTree();
                menuList.forEach(m -> {
                    if (m.getPermissionTreeVOList() != null && m.getPermissionTreeVOList().size() != 0) {
                        m.setButton(false);
                        getData(m.getPermissionTreeVOList(), roleIds);
                    }
                });

            }
        }

        return menuList;
    }

    @Override
    public RootResponse<PageResult<PermissionVO>> queryPermissionPage(PermissionDTO permissionDTO) {
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        wrapper.eq(SysPermission::getIsSoftDelete, false);
        if (StringUtils.isNotBlank(permissionDTO.getId())) {
            wrapper.eq(SysPermission::getPermissionPid, permissionDTO.getId());
        }else {
            wrapper.isNull(SysPermission::getPermissionPid);
        }
        wrapper.orderByDesc(SysPermission::getCreateDateTime, SysPermission::getId);
//        if ("00".equals(permissionDTO.getType())) {
            PageHelper.startPage(permissionDTO.getPageNum(), permissionDTO.getPageSize());
            var permissions = baseMapper.selectList(wrapper);
            var pageInfo = PageInfo.of(permissions);
            var pageList = pageInfo.getList();
            return RootResponse.success(PageResult.page(pageList, pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal()));
//        } else {
//            var permissions = baseMapper.selectList(wrapper);
//            return RootResponse.success(permissions);
//        }
    }

    @Override
    public RootResponse treePermission() {
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        List<PermissionTreeVO> permissionTreeVOList=new ArrayList<>();
        wrapper.eq(SysPermission::getIsSoftDelete, false);
      baseMapper.selectList(wrapper).forEach(p->{
          var permissionTreeVO=new PermissionTreeVO();
          BeanCopyUtils.copy(p,permissionTreeVO);
          permissionTreeVOList.add(permissionTreeVO);
      });
        if( permissionTreeVOList!=null&&permissionTreeVOList.size()!=0){
            MenuTree menuTree =new MenuTree(permissionTreeVOList);
            var  menuList=menuTree.builTree();
            return RootResponse.success(menuList);
        }
        return RootResponse.success();
    }

    @Override
    public RootResponse createPermission(CreatePermissionDTO permissionDTO, LoginUserDTO userDTO) {
        //检查重名
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        wrapper.eq(SysPermission::getIsSoftDelete, false);
        wrapper.and(wrapper1 ->  wrapper1.eq(SysPermission::getRouter, permissionDTO.getRouter())).or().eq(SysPermission::getLabel, permissionDTO.getLabel());
        var permissions = baseMapper.selectList(wrapper);
        if (permissions.size() != 0) {
            return RootResponse.error("路由或名称已存在，请勿重复添加");
        }
        var permission = new SysPermission();
        BeanCopyUtils.copy(permissionDTO, permission);
        permission.setId(HandleUtils.UUID32());
        permission.setCreator(userDTO.getUsername());
        permission.setCreateDateTime(new Date());
        permission.setIsSoftDelete(false);
        if (StringUtils.isNotBlank(permissionDTO.getPermissionPid())) {
            var parent = baseMapper.selectById(permissionDTO.getPermissionPid());
            permission.setIdPath(parent.getIdPath() + "/" + permission.getId());
        } else {
            permission.setIdPath(permission.getId());
        }
        int i = baseMapper.insert(permission);
        return i == 1 ? RootResponse.success(permission) : RootResponse.error();
    }

    @Override
    public RootResponse updatePermissin(UpdatePermissionDTO permissionDTO, LoginUserDTO userDTO) {
        var wrapper1 = new LambdaQueryWrapper<SysPermission>();
        wrapper1.eq(SysPermission::getId, permissionDTO.getId());
        wrapper1.eq(SysPermission::getIsSoftDelete, false);
        var permission = baseMapper.selectOne(wrapper1);
        if (permission == null) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        //检查重名
        if (!permissionDTO.getRouter().equals(permission.getRouter())) {
            wrapper1.clear();
            wrapper1.eq(SysPermission::getIsSoftDelete, false);
            wrapper1.and(wrapper->wrapper.eq(SysPermission::getRouter, permissionDTO.getRouter()).or().eq(SysPermission::getActionUrl, permissionDTO.getActionUrl()));
            var permission2 = baseMapper.selectList(wrapper1);
            if (permission2.size() != 0||!permission2.get(0).getId().equals(permissionDTO.getId())) {
                return RootResponse.error("路由或名称已存在，请勿重复添加");
            }
        }
        BeanCopyUtils.copy(permissionDTO, permission);
        permission.setUpdater(userDTO.getUsername());
        permission.setUpdateDateTime(new Date());
        if (StringUtils.isNotBlank(permissionDTO.getPermissionPid())) {
            if (!permissionDTO.getPermissionPid().equals(permission.getPermissionPid())) {
                var parent = baseMapper.selectById(permissionDTO.getPermissionPid());
                permission.setIdPath(parent.getIdPath() + "/" + permission.getId());
            } else {
                permission.setIdPath(permission.getId());
            }
        }
        int i = baseMapper.updateById(permission);
        return i == 1 ? RootResponse.success(permission) : RootResponse.error();
    }

    @Override
    public RootResponse deletePermission(String permissionId, LoginUserDTO userDTO) {
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        wrapper.eq(SysPermission::getId, permissionId);
        wrapper.eq(SysPermission::getIsSoftDelete, false);
        var permission = baseMapper.selectOne(wrapper);
        if (permission == null) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        permission.setIsSoftDelete(true);
        permission.setUpdateDateTime(new Date());
        permission.setUpdater(userDTO.getUsername());
        baseMapper.updateById(permission);
        var wrapper1 = new LambdaQueryWrapper<SysPermission>();
        while (true){
            wrapper1.clear();

            wrapper1.eq(SysPermission::getPermissionPid, permissionId);
            wrapper1.eq(SysPermission::getIsSoftDelete, false);
             permission = baseMapper.selectOne(wrapper);
            if(permission==null){
                break;
            }
            else {
                permission.setIsSoftDelete(true);
                permission.setUpdateDateTime(new Date());
                permission.setUpdater(userDTO.getUsername());
                baseMapper.updateById(permission);
            }

        }
        // 根据权限Id删除角色和权限的关联关系
        var qWrapper = new LambdaQueryWrapper<SysRolePermission>();
        qWrapper.eq(SysRolePermission::getPermissionId, permissionId);
        rolePermissionMapper.delete(qWrapper);
        return RootResponse.success(permission);
    }

    @Override
    @Transactional
    public RootResponse changePermissionSort(List<PermissionSortDTO> sorts, LoginUserDTO userDTO) {
        try {
            if (sorts != null && !sorts.isEmpty()) {
                sorts.forEach(m -> {
                    if (StringUtils.isNotBlank(m.getId()) && m.getSort() != null) {
                        var pWrapper = new LambdaQueryWrapper<SysPermission>();
                        pWrapper.eq(SysPermission::getIsSoftDelete, false);
                        pWrapper.eq(SysPermission::getId, m.getId());
                        var cate = baseMapper.selectOne(pWrapper);
                        cate.setUpdater(userDTO.getUsername());
                        cate.setUpdateDateTime(new Date());
                        cate.setSort(m.getSort());
                        var c = baseMapper.updateById(cate);
                        if (c != 1) {
                            throw new PcbsException("修改顺序失败");
                        }
                    } else {
                        throw new PcbsException("顺序不能为空");
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return RootResponse.success();
    }

    @Override
    public RootResponse resetIdPath() {
        //顶层
        var wrapper = new LambdaQueryWrapper<SysPermission>();
        wrapper.eq(SysPermission::getIsSoftDelete, false);
        wrapper.isNull(SysPermission::getPermissionPid);
        wrapper.or();
        wrapper.eq(SysPermission::getPermissionPid, "");
        var parent = baseMapper.selectList(wrapper);
        if (HandleUtils.ListIsNotNull(parent)) {
            parent.forEach(m -> {
                m.setIdPath(m.getId());
            });
            this.updateBatchById(parent);
            setChildrenIdPath(parent);
        }
        return RootResponse.success();
    }

    private void setChildrenIdPath(List<SysPermission> parent) {
        if (HandleUtils.ListIsNotNull(parent)) {
            parent.forEach(m -> {
                var wrapper = new LambdaQueryWrapper<SysPermission>();
                wrapper.eq(SysPermission::getIsSoftDelete, false);
                wrapper.eq(SysPermission::getPermissionPid, m.getId());
                var children = baseMapper.selectList(wrapper);
                if (HandleUtils.ListIsNotNull(children)) {
                    children.forEach(n -> {
                        n.setIdPath(m.getIdPath() + "/" + n.getId());
                    });
                    this.updateBatchById(children);
                    setChildrenIdPath(children);
                }
            });
        }
    }

    private void getData( List<PermissionTreeVO> permissionTreeVOs,List<String> roleIds ){

        permissionTreeVOs.forEach(m->{
            if(m.getPermissionTreeVOList()!=null&&m.getPermissionTreeVOList().size()!=0){
                m.setButton(false);
                getData(m.getPermissionTreeVOList(),roleIds);
            }else {
                m.setButton(true);
             var   pageId=m.getId();
             m.setOperationsList( sysOperationMapper.selectRoleOperation(pageId,roleIds));
            }
        });
    }
    private void getDataAdmin( List<PermissionTreeVO> permissionTreeVOs,List<String> roleIds ){

        permissionTreeVOs.forEach(m->{
            if(m.getPermissionTreeVOList()!=null&&m.getPermissionTreeVOList().size()!=0){
                m.setButton(false);
                getDataAdmin(m.getPermissionTreeVOList(),roleIds);
            }else {
                m.setButton(true);
                var   pageId=m.getId();
                //admin按钮给所有
                m.setOperationsList(sysOperationMapper.selectRoleOperation(pageId,null));
            }
        });
    }
}
